<?php

namespace app\models;

use app\librarys\Tools;
use yii\mongodb\ActiveRecord;

/**
 * API访问日志
 * Class ApiOperateLog
 * @package app\models
 */
class ApiLog extends ActiveRecord
{
    /**
     * 添加日志
     * @param  $controllerId
     * @param $actionId
     * @param $getParams
     * @param $postParams
     * @param $account
     * @param $timestamp
     * @param $sign
     * @param $remoteAddr
     * @param $createDatetime
     * @return mixed|null|string
     */
    public static function add($controllerId, $actionId, $getParams, $postParams, $account, $timestamp, $sign, $remoteAddr, $createDatetime)
    {
        $log = new ApiLog();
        $log->_id = Tools::uuid();
        $log->controllerId = $controllerId;
        $log->actionId = $actionId;
        $log->getParams = $getParams;
        $log->postParams = $postParams;
        $log->account = $account;
        $log->timestamp = $timestamp;
        $log->sign = $sign;
        $log->remoteAddr = $remoteAddr;
        $log->createDatetime = $createDatetime;
        $log->durationTime = null;
        $log->exceptionCode = null;
        $log->exceptionMessage = null;
        $log->exceptionTraceMessage = null;
        $result = $log->save();
        if ($result == true) {
            return $log->_id;
        } else {
            return null;
        }
    }

    /**
     * 更新action执行时间
     * @param $id
     * @param $durationTime
     */
    public static function setDurationTime($id, $durationTime)
    {
        $log = self::find()->where(['_id' => $id])->one();
        $log->durationTime = $durationTime;
        $log->update();
    }

    /**
     * 设置错误信息
     * @param $id
     * @param \Exception $ex
     */
    public static function setException($id, $ex)
    {
        $log = self::find()->where(['_id' => $id])->one();
        $log->exceptionCode = $ex->getCode();
        $log->exceptionMessage = $ex->getMessage();
        $log->exceptionTraceMessage = Tools::getExceptionFullTraceAsString($ex);// $ex->getTraceAsString();
        $log->update();
    }

    /**
     * 根据id获取日志明细
     * @param $id
     * @return array|null|ActiveRecord
     */
    public static function getById($id)
    {
        $log = self::find()->where(['_id' => $id])->one();
        return $log;
    }

    /**
     * 获取日志总数
     * @param $controllerId
     * @param $actionId
     * @param $account
     * @param $durationTime
     * @param $startTime
     * @param $endTime
     * @param $isException
     * @return int
     */
    public static function getCount($controllerId, $actionId, $account, $durationTime, $startTime, $endTime, $isException)
    {
        $whereParams = [];

        if (!empty($controllerId)) {
            $whereParams['controllerId'] = $controllerId;
        }

        if (!empty($actionId)) {
            $whereParams['actionId'] = $actionId;
        }

        if (!empty($account)) {
            $whereParams['account'] = $account;
        }

        $items = self::find()->where($whereParams);

        if (!empty($isException)) {
            if (!empty($whereParams)) {
                $items->andWhere(['<>', 'exceptionCode', null]);
            } else {
                $items->where(['<>', 'exceptionCode', null]);
            }
        }

        if (!empty($durationTime)) {
            if (!empty($whereParams)) {
                $items->andWhere(['>=', 'durationTime', intval($durationTime)]);
            } else {
                $items->where(['>=', 'durationTime', intval($durationTime)]);
            }
        }


        if (!empty($startTime)) {
            $stime = strtotime($startTime);
            if (!empty($whereParams) || !empty($durationTime)) {
                $items->andWhere(['>=', 'createDatetime', $stime]);
            } else {
                $items->Where(['>=', 'createDatetime', $stime]);
            }
        }
        if (!empty($endTime)) {
            $etime = strtotime($endTime);
            if (!empty($whereParams) || !empty($durationTime) || !empty($startTime)) {
                $items->andWhere(['<', 'createDatetime', $etime]);
            } else {
                $items->where(['<', 'createDatetime', $etime]);
            }
        }
        return $items->count();
    }

    /**
     * 获取日志列表
     * @param $page
     * @param $pageSize
     * @param $controllerId
     * @param $actionId
     * @param $account
     * @param $durationTime
     * @param $startTime
     * @param $endTime
     * @param $isException
     * @return array|ActiveRecord
     */
    public static function getList($page, $pageSize, $controllerId, $actionId, $account, $durationTime, $startTime, $endTime, $isException)
    {
        $whereParams = [];

        if (!empty($controllerId)) {
            $whereParams['controllerId'] = $controllerId;
        }

        if (!empty($actionId)) {
            $whereParams['actionId'] = $actionId;
        }

        if (!empty($account)) {
            $whereParams['account'] = $account;
        }

        $items = self::find()->where($whereParams);

        if (!empty($isException)) {
            if (!empty($whereParams)) {
                $items->andWhere(['<>', 'exceptionCode', null]);
            } else {
                $items->where(['<>', 'exceptionCode', null]);
            }
        }

        if (!empty($durationTime)) {
            if (!empty($whereParams)) {
                $items->andWhere(['>=', 'durationTime', intval($durationTime)]);
            } else {
                $items->where(['>=', 'durationTime', intval($durationTime)]);
            }
        }


        if (!empty($startTime)) {
            $stime = strtotime($startTime);
            if (!empty($whereParams) || !empty($durationTime)) {
                $items->andWhere(['>=', 'createDatetime', $stime]);
            } else {
                $items->Where(['>=', 'createDatetime', $stime]);
            }
        }
        if (!empty($endTime)) {
            $etime = strtotime($endTime);
            if (!empty($whereParams) || !empty($durationTime) || !empty($startTime)) {
                $items->andWhere(['<', 'createDatetime', $etime]);
            } else {
                $items->where(['<', 'createDatetime', $etime]);
            }
        }

        return $items->offset($page * $pageSize)
            ->limit($pageSize)
            ->orderBy('createDatetime desc')
            ->asArray()
            ->all();
    }

    public function attributes()
    {
        return [
            '_id',  // pk api请求日志
            'controllerId',  // 请求的controller id
            'actionId',  // 请求的 action id
            'getParams',  // 请求的get参数数组
            'postParams',  // 请求的post参数数组
            'account',
            'timestamp',  // get请求中的时间戳
            'sign',  // get请求中的签名
            'remoteAddr',  // 访问的来源地址ip
            'createDatetime',  // 请求时间
            'durationTime',  // 请求持续时间(毫秒)
            'exceptionCode',
            'exceptionMessage',
            'exceptionTraceMessage'
        ];
    }
}